#ifndef NET_TCPCLIENT_H
#define NET_TCPCLIENT_H

#include "callback.h"
#include "utility/Noncopyable.h"

#include <mutex>

class Connector;
class Eventloop;
class Sockaddr;
class Socket;

class TCPClient final {
public:
    TCPClient(
        Eventloop &loop, const Sockaddr &addr, std::string name, bool retry = false);
    ~TCPClient();

    TCPConnectionPtr connection() const {
        std::lock_guard guard{_mutex};
        return _connection;
    }

    void set_connection_callback(const ConnectionCallback &callback) {
        _connectionCallback = callback;
    }
    void set_drain_callback(const DrainCallback &callback) {
        _drainCallback = callback;
    }
    void set_message_callback(const MessageCallback &callback) {
        _messageCallback = callback;
    }

    void connect();
    void disconnect();
    void send(const std::string &message);
    void send(std::string &&message);
    void stop();    


private:
    NONCOPYABLE(TCPClient);

    void _close_callback(const TCPConnectionPtr &connection);
    void _destroy_connection(const TCPConnectionPtr &connection, long count);
    void _new_connection_callback(std::unique_ptr<Socket> &&socket);

    mutable std::mutex _mutex;
    const std::string _name;
    ConnectionCallback _connectionCallback;
    DrainCallback _drainCallback;
    MessageCallback _messageCallback;
    const std::shared_ptr<Connector> _connector;
    TCPConnectionPtr _connection;
    Eventloop &_loop;
    int _connectionID;
    const bool _retry;
    bool _connecting;
};


#endif